package ch.ethz.fcl.metrobuzz.render;

import org.lwjgl.opengl.GL11;

import ch.ethz.fcl.metrobuzz.MBContainer;
import ch.ethz.fcl.metrobuzz.data.texture.MBTexture;
import ch.ethz.fcl.metrobuzz.render.techniques.colors.MBColorTable;
import ch.ethz.fcl.metrobuzz.render.techniques.projection.Projection;
import ch.ethz.fcl.metrobuzz.spatialindex.object2d.Point2D;
import ch.ethz.fcl.metrobuzz.spatialindex.object2d.Polygon;
import ch.ethz.fcl.metrobuzz.spatialindex.object2d.Rectangle;
import ch.ethz.fcl.metrobuzz.spatialindex.object3d.Point3D;
import ch.ethz.fcl.metrobuzz.tools.MBGL;
import ch.ethz.fcl.metrofont.Pen;

/**
 * used to render the direction and scale attributes of a map
 * 
 * @author Zeng Wei
 * @email zeng@arch.ethz.ch
 * 
 */
public class MapAttributesRender {
	private MBContainer container;
	private float x = 22.0f, y = 20.0f; // start position of the indicators
	private float width = 170.0f, height = 45.0f;

	private float directionWidth = 30.0f; // width of north icon in pixels
	private float maxScaleWidth = 120.0f;// maximum width of the scale

	public MapAttributesRender(MBContainer container) {
		this.container = container;
	}

	public void render() {
		MBGL.enableBlend();

		renderShadow();
		renderDirection();
		renderScale();
		renderBoundary();

		GL11.glDisable(GL11.GL_BLEND);
	}

	private void renderShadow() {
		Projection proj = container.getViewer().getProjection();

		Point3D btm_left_point = proj.getWorldCoord(new Point2D(x, y), 0);
		Point3D top_right_point = proj.getWorldCoord(new Point2D(x + width, y
				+ height), 0);

		Rectangle shadowRegion = new Rectangle(btm_left_point.getX(),
				btm_left_point.getY(), top_right_point.getX(),
				top_right_point.getY());

		MBTexture.renderTexture(container.getData().getTexture().getShadow(),
				shadowRegion);
	}

	private void renderDirection() {
		Projection proj = container.getViewer().getProjection();

		Point3D btm_left_point = proj.getWorldCoord(new Point2D(x, y - 8), 0);
		float width = proj.getWorldDistance(directionWidth);
		float height = width * 2;
		Rectangle iconRegion = new Rectangle(btm_left_point.getX(),
				btm_left_point.getY(), btm_left_point.getX() + width,
				btm_left_point.getY() + height);

		MBTexture.renderTexture(
				container.getData().getTexture().getNorthIcon(), iconRegion);
	}

	private void renderScale() {
		Projection proj = container.getViewer().getProjection();
		float length = proj.getWorldDistance(maxScaleWidth);

		float distance = container.getData().getScene().getBound()
				.getWorldDist(length);

		Point3D start = proj.getWorldCoord(new Point2D(x + directionWidth + 10,
				y + height / 4.0f), 0);
		float upLength = proj.getWorldDistance(height / 4.0f);

		GL11.glLineWidth(2.0f);
		GL11.glColor4f(0, 0, 0, 1.0f);
		GL11.glBegin(GL11.GL_LINES);
		GL11.glVertex3f(start.getX(), start.getY(), 0);
		GL11.glVertex3f(start.getX() + length, start.getY(), 0);

		GL11.glVertex3f(start.getX() + upLength / 10, start.getY() - upLength
				/ 10, 0);
		GL11.glVertex3f(start.getX() + upLength / 10, start.getY() + upLength
				- upLength / 10, 0);

		GL11.glVertex3f(start.getX() + length - upLength / 10, start.getY()
				- upLength / 10.0f, 0);
		GL11.glVertex3f(start.getX() + length - upLength / 10, start.getY()
				+ upLength - upLength / 10.0f, 0);
		GL11.glEnd();

		// render exact scale number
		String scale = (int) distance + " m";
		float fontSize = proj.getWorldDistance(height / 2);
		float fontLen = container.getFont().getLength(scale, fontSize);
		container.getFont().display(
				scale,
				new Pen(start.getX() + length / 2 - fontLen / 2, start.getY(),
						fontSize));
	}

	protected void renderBoundary() {
		for (Polygon zone : container.getData().getSGInfo().getSGZones()
				.getSingaporeZone()) {
			zone.renderArea();

			GL11.glLineWidth(2.0f);
			MBColorTable.assignColor(MBColorTable.BLACK, 0.5f);
			zone.render();
		}
	}
}
